// Copyright 2018 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// This file contains pin mapping information that is specific to the Allwinner
// A20 model.

package nuc98x

import (
	"strings"

	"openzbox.com/driver/conn/pin"
	"openzbox.com/driver/host/sysfs"
)

// mappingA20 describes the mapping of the A20 processor gpios to their
// alternate functions.
//
// It omits the in & out functions which are available on all gpio.
//
// The mapping comes from the datasheet page 241:
// http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf
var mappingDK61YC = map[string][8]pin.Func{
	"PA0": {"QSPI0_SS1", "", "I2C0_SDA", "UART1_RXD", "EINT0", "TM0_ECNT", "CAN3_RXD", ""},
	"PA1": {"EBI_nCS2", "EBI_MCLK", "I2C0_SCL", "UART1_TXD", "EINT1", "TM1_ECNT", "CAN3_TXD", ""},
	"PA2": {"UART6_CTS", "I2S_LRCK", "SC0_CD", "JTAG1_TDO", "", "TM2_ECNT", "", ""},

	"PA3":  {"ERXD0", "SPI1_MISO", "UART2_RX", "GRXD0"},
	"PA4":  {"ETXD3", "SPI1_CS1", "", "GTXD3"},
	"PA5":  {"ETXD2", "SPI3_CS0", "", "GTXD2"},
	"PA6":  {"ETXD1", "SPI3_CLK", "", "GTXD1"},
	"PA7":  {"ETXD0", "SPI3_MOSI", "", "GTXD0"},
	"PA8":  {"ERXCK", "SPI3_MISO", "", "CRXCK"},
	"PA9":  {"ERXERR", "SPI3_CS1", "", "GNULL", "I2S1_MCLK"},
	"PA10": {"ERXDV", "", "UART1_TX", "GRXCTL"},
	"PA11": {"EMDC", "", "UART1_RX", "GMDC"},
	"PA12": {"EMDIO", "UART6_TX", "UART1_RTS", "GMDIO"},

	"PB0":  {"I2C0_SCL"},
	"PB1":  {"I2C0_SDA"},
	"PB2":  {"PWM0"},
	"PB3":  {"IR0_TX", "", "SPDIF_MCLK", "", "STANBYWFI"},
	"PB4":  {"IR0_RX"},
	"PB5":  {"I2S0_MCLK", "AC97_MCLK"},
	"PB6":  {"I2S0_SCK", "AC97_SCK"},
	"PB7":  {"I2S0_WS", "AC97_SYNC"},
	"PB8":  {"I2S0_DOUT0", "AC97_DOUT"},
	"PB13": {"QSPI0_SS1", "", "I2C0_SDA", "UART1_RXD", "EINT0", "TM0_ECNT", "CAN3_RXD", ""},

	"PC0":  {"NWE#", "SPI0_MOSI"},
	"PC1":  {"NALE", "SPI0_MISO"},
	"PC2":  {"NCLE", "SPI0_CLK"},
	"PC3":  {"NCE1"},
	"PC4":  {"NCE0"},
	"PC5":  {"NRE#"},
	"PC6":  {"NRB0", "SDC2_CMD"},
	"PC7":  {"NRB1", "SDC2_CLK"},
	"PC8":  {"NDQ0", "SDC2_D0"},
	"PC9":  {"NDQ1", "SDC2_D1"},
	"PC10": {"NDQ2", "SDC2_D2"},
	"PC11": {"NDQ3", "SDC2_D3"},
	"PC12": {"NDQ4"},
	"PC13": {"NDQ5"},
	"PC14": {"NDQ6"},
	"PC15": {"NDQ7"},

	"PD0":  {"LCD0_D0", "LVDS0_VP0"},
	"PD1":  {"LCD0_D1", "LVDS0_VN0"},
	"PD2":  {"LCD0_D2", "LVDS0_VP1"},
	"PD3":  {"LCD0_D3", "LVDS0_VN1"},
	"PD4":  {"LCD0_D4", "LVDS0_VP2"},
	"PD5":  {"LCD0_D5", "LVDS0_VN2"},
	"PD6":  {"LCD0_D6", "LVDS0_VPC"},
	"PD7":  {"LCD0_D7", "LVDS0_VNC"},
	"PD8":  {"LCD0_D8", "LVDS0_VP3"},
	"PD9":  {"LCD0_D9", "LVDS0_VN3"},
	"PD10": {"LCD0_D10", "LVDS1_VP0"},
	"PD11": {"LCD0_D11", "LVDS1_VN0"},
	"PD12": {"LCD0_D12", "LVDS1_VP1"},
	"PD13": {"LCD0_D13", "LVDS1_VN1"},
	"PD14": {"LCD0_D14", "LVDS1_VP2"},
	"PD15": {"LCD0_D15", "LVDS1_VN2"},

	"PE0":  {"TS0_CLK", "CSI0_PCLK"},
	"PE1":  {"TS0_ERR", "CSI0_MCLK"},
	"PE2":  {"TS0_SYNC", "CSI0_HSYNC"},
	"PE3":  {"TS0_DLVD", "CSI0_VSYNC"},
	"PE4":  {"TS0_D0", "CSI0_D0"},
	"PE5":  {"TS0_D1", "CSI0_D1"},
	"PE6":  {"TS0_D2", "CSI0_D2"},
	"PE7":  {"TS0_D3", "CSI0_D3"},
	"PE8":  {"TS0_D4", "CSI0_D4"},
	"PE9":  {"TS0_D5", "CSI0_D5"},
	"PE10": {"TS0_D6", "CSI0_D6"},
	"PE11": {"TS0_D7", "CSI0_D7"},
	"PE12": {"TS0_D7", "CSI0_D7"},

	"PF0":  {"SDC0_D1", "", "JTAG1_TMS"},
	"PF1":  {"SDC0_D0", "", "JTAG1_TDI"},
	"PF2":  {"SDC0_CLK", "", "UART0_TX"},
	"PF3":  {"SDC0_CMD", "", "JTAG1_TDO"},
	"PF4":  {"SDC0_D3", "", "UART0_RX"},
	"PF5":  {"SDC0_D2", "", "JTAG1_TCK"},
	"PF6":  {"SDC0_D1", "", "JTAG1_TMS"},
	"PF7":  {"SDC0_D0", "", "JTAG1_TDI"},
	"PF8":  {"SDC0_CLK", "", "UART0_TX"},
	"PF9":  {"SDC0_CMD", "", "JTAG1_TDO"},
	"PF10": {"SDC0_D3", "", "UART0_RX"},
	"PF11": {"SDC0_D2", "", "JTAG1_TCK"},
	"PF12": {"SDC0_D2", "", "JTAG1_TCK"},

	"PG0":  {"TS1_CLK", "CSI1_PCLK", "SDC1_CMD"},
	"PG1":  {"TS1_ERR", "CSI1_MCLK", "SDC1_CLK"},
	"PG3":  {"TS1_DVLD", "CSI1_VSYNC", "SDC1_D1"},
	"PG5":  {"TS1_D1", "CSI1_D1", "SDC1_D3", "CSI0_D9"},
	"PG6":  {"TS1_D2", "CSI1_D2", "UART3_TX", "CSI0_D10"},
	"PG7":  {"TS1_D3", "CSI1_D3", "UART3_RX", "CSI0_D11"},
	"PG8":  {"TS1_D4", "CSI1_D4", "UART3_RTS", "CSI0_D12"},
	"PG9":  {"TS1_D5", "CSI1_D4", "UART3_CTS", "CSI0_D13"},
	"PG11": {"TS1_D7", "CSI1_D7", "UART4_RX", "CSI0_D15"},
	"PG12": {"TS1_D6", "CSI1_D6", "UART4_TX", "CSI0_D14"},
	"PG13": {"TS1_D6", "CSI1_D6", "UART4_TX", "CSI0_D14"},
	"PG14": {"TS1_D6", "CSI1_D6", "UART4_TX", "CSI0_D14"},
	"PG15": {"TS1_D6", "CSI1_D6", "UART4_TX", "CSI0_D14"},
}

// mapA20Pins uses mappingA20 to actually set the altFunc fields of all gpio
// and mark them as available.
//
// It is called by the generic allwinner processor code if an A20 is detected.
func mapDK61YCPins() error {
	for name, altFuncs := range mappingDK61YC {
		//log.Infof("xxxxxxxxx%s",name)
		pin := cpupins[name]
		pin.altFunc = altFuncs
		pin.available = true
		if strings.Contains(string(altFuncs[4]), "_EINT") ||
			strings.Contains(string(altFuncs[3]), "_EINT") {
			pin.supportEdge = true
		}

		// Initializes the sysfs corresponding pin right away.
		pin.sysfsPin = sysfs.Pins[pin.Number()]
	}
	return nil
}
